<?php

declare(strict_types=1);
namespace App\Middleware;

use Hyperf\Context\Context;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Contract\ResponseInterface as HttpResponse;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

/**
 * api认证中间件
 * 作者 薛原
 * Class TokenMiddleware
 * @package App\Middleware
 */
class TokenMiddleware implements MiddlewareInterface {

    protected ContainerInterface $container;

    protected RequestInterface $request;

    protected HttpResponse $response;
    public function __construct(ContainerInterface $container, HttpResponse $response, RequestInterface $request)
    {
        $this->container = $container;
        $this->response = $response;
        $this->request = $request;
    }

    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        $url = $request->getUri()->getPath();

        /**
         * 登录注册接口不拦截
         */
        if(strpos($url,"auth/login")){
            return $handler->handle($request);
        }
        if(strpos($url,"auth/register")){
            return $handler->handle($request);
        }
        
        $token = "";
        /*
         * 从header  Authorization 中取token
         * 这里做了两种逻辑，一个是走header里面取token,用于线上环境使用，另外新增了走传参获取，便于开发调试。
         */
        $header_authorization = $request->getHeader("Authorization");
        if($header_authorization && count($header_authorization) == 1){
            $header_authorization_string = $header_authorization[0];
            $header_authorization_data_arr = explode(" ",$header_authorization_string);
            if(count($header_authorization_data_arr) == 2){
                $token = $header_authorization_data_arr[1];
            }
        }
        if(isset($request->getQueryParams()['token'])){
            $token = $request->getQueryParams()['token'];
        }
        $token_data = json_decode(base64_decode($token),true);

        if($token_data){
            Context::set("login_user_id",$token_data['acl']['user_id']);
            Context::set("login_user_role",$token_data['acl']['role']);
        }else{
            return $this->response->json(["code"=>40002,"message"=>"token无效","errors"=>[],"timestamp"=>time()]);
        }
        return $handler->handle($request);
    }
}